package chat;

import unit.MyConfig;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

/**
 * 登录对话框
 */
class Login extends JFrame {
	private final int width;
	private final Init init;

	Login(int login_width, int login_height, Init init) {
		this.width = login_width;
		this.init = init;
		setTitle("请输入进行登入");
		setSize(login_width, login_height);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
		setLayout(null);
		setResizable(false);
		textInput();
	}

	private void textInput() {
		int top = 45;
		int height_ = 35;
		JLabel label = new JLabel("聊天名:");
		JTextField jTextField = new JTextField();
		JButton jButton = new JButton("确定");

		add(label);
		add(jButton);
		add(jTextField);
		label.setBounds(25, top, width / 10 * 2, height_);
		jTextField.setBounds(width / 10 * 2 + 25, top, width / 10 * 4, height_);
		jButton.setBounds(width / 10 * 7, top, width / 10 * 2, height_);

		// 将文本框绑定回车“发送消息”
		jTextField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				if (e.getKeyChar() == KeyEvent.VK_ENTER) {
					try {
						handleDo(jTextField);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
				}
			}
		});
		jButton.addActionListener((e) -> {
			try {
				handleDo(jTextField);
			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}
		});
	}

	private void handleDo(JTextField jTextField) throws InterruptedException {
		// 获取聊天名
		String myName = jTextField.getText();
		if (!myName.equals("")) {
			init.myOnlineName = myName;
			//
			init.printStream.println("userName:" + myName);
			Thread.sleep(100);
			init.printStream.println("查询在线列表");
			// 关闭小窗口
			setVisible(false);
		}
	}
}

/**
 * 初始化主页面
 */
class Init extends JFrame {
	private final MyConfig config;
	// ”在线列表“菜单节点列表
	private final ArrayList<JTextField> getTextPane = new ArrayList<>();
	private JTextArea textArea;
	private Socket socket;
	protected PrintStream printStream;
	private String tempStr;
	protected String myOnlineName = " ";
	private String msgFOR = "G:";
	// ”在线用户列表“相关属性
	private JScrollPane jsp;
	private JPanel panel2;
	// 设置当前选中带有颜色的标签
	private String onTextPane = " ";

	Init(MyConfig config) {
		this.config = config;
		setTitle("weChat");
		setSize(config.getJFrameSizeWidth(), config.getJFrameSizeHeight() + 38);
		setLocationRelativeTo(null);
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				try {
					printStream.println("exit:" + myOnlineName);
					Thread.sleep(100);
					printStream.println("查询在线列表");
					printStream.close();
				} catch (InterruptedException interruptedException) {
					System.out.println(interruptedException);
				}
				System.exit(0);
			}
		});
		setVisible(true);
		setLayout(null);
		setResizable(false);
		initSocket();
		left_bar();
		right_bar();
	}

	/**
	 * 初始化socket连接
	 */
	private void initSocket() {
		try {
			socket = new Socket(config.getIP(), config.getPORT());
			printStream = new PrintStream(socket.getOutputStream());
			new Thread(() -> {
				try {
					Scanner scanner = new Scanner(socket.getInputStream());
					while (scanner.hasNext()) {
						tempStr = scanner.nextLine();
						// 创建“在线用户“利列表
						if (tempStr.contains("【在线人数】：")) {
							new Thread(this::change_online_list).start();
						}
						if (tempStr.contains("【发送消息】：")) {
							new Thread(() -> {
								tempStr = tempStr.replace("【发送消息】：", "");
								textArea.append(tempStr + " \n");
							}).start();
						}
					}
					scanner.close();
				} catch (IOException e) {
//					e.printStackTrace();
					System.out.println(e);
				}
			}).start();
		} catch (IOException e) {
			// 网络发生错误
			System.out.println(e);
			JOptionPane.showConfirmDialog(null, "网路发生错误！", "网络错误", JOptionPane.DEFAULT_OPTION);
			System.exit(0);
		}
	}

	/**
	 * 生成“用户列表”窗体
	 */
	private void change_online_list() {
		tempStr = tempStr.replace("【在线人数】：", "");
		panel2.removeAll();
		if (!tempStr.equals("")) {
			// 遍历在线列表，添加在线用户
			for (int i = 0; i < Arrays.asList(tempStr.split("-")).size(); i++) {
				// 是否能够显示（是否重复）
				if (Arrays.asList(tempStr.split("-")).get(i).equals("")) {
					continue;
				}
				// 创建小用户窗体
				JTextField textPane = new JTextField(Arrays.asList(tempStr.split("-")).get(i), 8);
				panel2.add(textPane);
				// 设置样式
				textPane.setPreferredSize(new Dimension(config.getJPanelLeftWidth(), 45));
				textPane.setFont(new Font("微软雅黑", Font.BOLD, 16));
				textPane.setForeground(Color.BLACK);
				textPane.setHorizontalAlignment(JTextField.CENTER);
				textPane.setEditable(false);
				textPane.setBackground(Color.WHITE);
//				textPane.setEnabled(false);
				textPane.setVisible(true);
				boolean a = true;
				// 判断是否是被点击（私聊）过的组件
				if (onTextPane.equals(Arrays.asList(tempStr.split("-")).get(i))) {
					textPane.setBackground(Color.yellow);
					a = false;
				}
				// 过滤自己的组件
				if (Arrays.asList(tempStr.split("-")).get(i).equals(myOnlineName))
					textPane.setBackground(new Color(238, 238, 238, 255));
				// 将”用户名“布局添加到数组里面
				getTextPane.add(textPane);
				// 添加监听
				add_lister(textPane, a);
				panel2.setPreferredSize(
						new Dimension(config.getJPanelLeftWidth() - 20, Arrays.asList(tempStr.split("-")).size() * 47));
			}
			jsp.getViewport().add(panel2);
		}
	}

	/**
	 * 监听“在线用户菜单” 实现点击用户“私聊” “取消私聊”功能
	 */
	private void add_lister(JTextField textPane, boolean a) {
		textPane.addMouseListener(new MouseListener() {
			// 判断是否点击过 false未点击过
			boolean active = a;

			@Override
			public void mouseClicked(MouseEvent e) {
				String m = textPane.getText();
				onTextPane = m;
				for (JTextField s : getTextPane) {
					if (!s.getText().equals(m) && !s.getText().equals(myOnlineName)) {
						s.setBackground(Color.white);
					}
				}
				// 不是私聊自己
				if (!m.equals(myOnlineName)) {
					if (active) {
						textPane.setBackground(Color.yellow);
						textArea.append("当前私聊：" + m + "\n");
						msgFOR = "P:" + m + "-";
						active = false;
					} else {
						textArea.append("取消私聊\n");
						textPane.setBackground(Color.white);
						msgFOR = "G:";
						active = true;
					}
				}
			}

			@Override
			public void mousePressed(MouseEvent e) {

			}

			@Override
			public void mouseReleased(MouseEvent e) {

			}

			@Override
			public void mouseEntered(MouseEvent e) {

			}

			@Override
			public void mouseExited(MouseEvent e) {

			}
		});
	}

	/**
	 * 当用户主动离线，执行此函数
	 */
	private void remove_doc(String rmName) {
		for (JTextField jtd : getTextPane) {
			if (jtd.getText().equals(rmName)) {
				jtd.setText("离线");
			}
		}
	}

	/**
	 * 左侧窗体集成
	 */
	private void left_bar() {
		// 首次获取“在线列表”， 生成在线菜单
		printStream.println("查询在线列表");
		JPanel contentPane = new JPanel();
		contentPane.setSize(config.getJPanelLeftWidth(), config.getJPanelLeftHeight());
		add(contentPane);

		// “通讯录”滚动栏
		jsp = new JScrollPane();
		contentPane.add(jsp);
		jsp.setSize(config.getJPanelLeftWidth(), config.getJPanelLeftHeight());
		jsp.validate();
		jsp.setVisible(true);
		panel2 = new JPanel();
	}

	/**
	 * 右侧窗体集成
	 */
	private void right_bar() {
		textArea = new JTextArea();
		JScrollPane jsp = new JScrollPane(textArea);
		add(jsp);
		jsp.setBounds(config.getJPanelLeftWidth(), 2, config.getChatSendBoxWidth() - 20, config.getChatSendBoxHeight());
		// 设置提示信息
		textArea.setText("已连接\n");
		textArea.setEditable(false);
		textArea.setFont(new Font("微软雅黑", Font.BOLD, 20));
		textArea.setForeground(Color.BLACK);
		
		// 聊天窗体
		JPanel jp = new JPanel();
		jp.setBounds(config.getJPanelLeftWidth(), config.getChatSendBoxHeight(), config.getInputBoxWidth(),
				config.getInputBoxHeight());
		add(jp);

		JTextField jtf = new JTextField(30);
		jp.add(jtf);
		// 将文本框绑定回车“发送消息”
		jtf.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				if (e.getKeyChar() == KeyEvent.VK_ENTER) {
					doSend(jtf);
				}
			}
		});
		jtf.setBounds(10, 10, 8 * (config.getInputBoxWidth() / 10), config.getInputBoxHeight() - 15);
		JButton jb = new JButton("发送");
		// “发送”按钮的绑定点击事件
		jb.addActionListener((e) -> doSend(jtf));
		jp.add(jb);
		jb.setBounds(8 * (config.getInputBoxWidth() / 10) + 15, 10, config.getInputBoxWidth() / 10,
				config.getInputBoxHeight() - 15);
	}

	/**
	 * ”发送消息“函数， 处理发送的消息
	 */
	private void doSend(JTextField jtf) {
		String mySendString = jtf.getText();
		System.out.println("mySendString " + mySendString);
		// 判断发送消息是否为空
		if (!mySendString.isEmpty()) {
			// 退出功能 关闭当前窗口
			if (mySendString.contains("exit:")) {
				remove_doc(myOnlineName);
				printStream.println(mySendString + myOnlineName);
				// 线程等待100毫秒后退出
				new Thread(() -> {
					try {
						Thread.sleep(100);
						System.exit(0);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}).start();
			}
			// 过滤多余字符串
			if (mySendString.contains("userName:")) {
				printStream.println(mySendString);
				myOnlineName = mySendString.split(":")[1];
			}
			// 过滤掉 “：”号
			if (!mySendString.contains(":")) {
				printStream.println(msgFOR + mySendString);
				try {
					// 线程休眠2毫秒，防止两段信息冲突
					Thread.sleep(200);
				} catch (InterruptedException ex) {
					ex.printStackTrace();
				}
				// 每次发送消息获取在线列表
				printStream.println("查询在线列表");
			}
			if (mySendString.contains(":")) {
				textArea.append("请不要带有“:”号！");
			}
			if (mySendString.contains("-")) {
				textArea.append("请不要带有“-”号！");
			}
			jtf.setText("");
		}
	}
}

public class ChatClient {
	public static void main(String[] args) {
		MyConfig config = new MyConfig(800, 500, 160, 50, "127.0.0.1", 6666);
		Init init = new Init(config);
		new Login(350, 200, init);
	}
}
